define(['jquery', 'knockout', 'dataservice', 'eventbus', 'util'], function ($, ko, ds, eventbus, util) {
	return function () {
		// List of searches in the search history.
		let searches = ko.observable({});
		// The search term provided by the user.
		let searchInput = ko.observable("");
		// A list of questions contained within a search result.
		let searchResults = ko.observable({});
		// The error message presented to the user.
		let errorStatus = ko.observable("Please search");

		// Retrieve searches and updates the error message.
		let retrieveSearches = function (data) {
			if (data.total == 0) errorStatus("No results");
			else errorStatus("");
			// Update the lists of questions with minified questions.
			searchResults(data.questions.map(function (question) {
				return util.minifyQuestion(question);
			}));

			// Add pagination.
			let paginationData = {
				currentUrl: data.currentPageUrl,
				firstUrl: data.firstPageUrl,
				prevUrl: data.previousPageUrl,
				nextUrl: data.nextPageUrl,
				lastUrl: data.lastPageUrl
			}
			// Notify the other components about the updated list of searches.
			eventbus.publish("searchesLoaded", paginationData);
		}

		// Click callback for the search button.
		let searchSubmit = function () {
			// TODO: move the hardcoded url out of this component to dataservice.
			let searchUrl = "https://localhost:5001/api/searches/search/" + searchInput();
			ds.getSearches(retrieveSearches, searchUrl);
		}

		// Get searches by url? TODO: clarify this.
		let getSearches = function (url) {
			ds.getSearches(retrieveSearches, url);
		}

		// Retrieve questions and update the list of searches with a minified search object.
		let retrieveQuestions = function (data) {
			// Update the list of searches with elements containing a human readable search date.
			searches(data.searches.map(
				function (searchResult) {
					// TODO: write this date conversion nicer.
					searchResult.searchDate = new Date(searchResult.searchDate * 1000).toString().slice(0, 15);
					return searchResult;
				}
			));


			// TODO: Hook up global pagination.
			let paginationData = {
				currentUrl: data.currentPageUrl,
				firstUrl: data.firstPageUrl,
				prevUrl: data.previousPageUrl,
				nextUrl: data.nextPageUrl,
				lastUrl: data.lastPageUrl
			}
			// Notify the other components about loaded search history.
			eventbus.publish("searchHistoryLoaded", paginationData);
		}

		// Initialization of the search history.
		ds.getSearchHistory(retrieveQuestions);

		// Retrieves the search history with a given url.
		let getSearchHistory = function (url) {
			ds.getSearchHistory(retrieveQuestions, url);
		}

		// Click callback for the search history item.
		// It searches again for that search text displayed in the search history.
		let search = function (data) {
			searchInput(data.searchText);
			searchSubmit();
		}

		// Click callback for the question item in the search result.
		let navigateToDetails = function (question) {
			localStorage.setItem("selectedQuestionUrl", question.questionUrl);
			eventbus.publish("changeComponentEvent", "question-details");
		}

		// Expose the properties relevant to the UI.
		return {
			title: 'Search & History',
			searches,
			searchInput,
			search,
			searchSubmit,
			searchResults,
			getSearchHistory,
			getSearches,
			navigateToDetails,
			errorStatus
		}
	}
});